feat(language-server): lazy document state via ensureCurrent + pull diagnostics#887
Draft
SevInf wants to merge 5 commits into
Draft
feat(language-server): lazy document state via ensureCurrent + pull diagnostics#887SevInf wants to merge 5 commits into
SevInf wants to merge 5 commits into
Conversation
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io>
…eCurrent seam Key the per-project document cache on TextDocument.version: update() skips recompute at an unchanged version, ensureCurrent(project, uri) is the single materialize-on-read seam for completion, semantic tokens, and folding, and the per-request whole-text compare (currentDocumentArtifact) is gone. Config reloads invalidate cached versions so the next read recomputes against the new stack. Push diagnostics on didChange are unchanged. Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io>
Advertise diagnosticProvider ({ interFileDependencies: false,
workspaceDiagnostics: false } — single-input implementation scope, to flip
with the future multi-input symbol table) when the client supports
textDocument/diagnostic, and serve full reports through the ensureCurrent
seam via a project-scoped report builder that can carry relatedDocuments
later. For pull clients didOpen/didChange become invalidate-only and config
changes request workspace/diagnostic/refresh (gated on refreshSupport)
instead of republishing; push clients keep the previous eager publish
behavior. Exactly one transport is ever active per client.
Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io>
Section 2 still claimed a reparse on every change, contradicting the pull-diagnostics description: parsing happens at most once per document version, when a read triggers materialization. Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io>
…n report, and trace Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io>
bc000fb to
2c5a078
Compare
size-limit report 📦
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reworks the language server's document-state lifecycle from eager, defensive reparse to invalidate-on-change + lazily materialize-on-read, synchronously, and moves diagnostics from push to LSP 3.17 pull (
textDocument/diagnostic). Implements thelsp-document-statespec committed as this PR's first commit (projects/lsp-document-state/).Changes
src/project-artifacts.ts,src/server.ts):ensureCurrent(project, uri)is the single synchronous materialize-on-read seam.CachedDocumentcarries the last-parsedversion; a read at an unchanged version does zero parsing, and an edit-then-immediate-read costs exactly one parse.currentDocumentArtifact— the per-request whole-document text compare + defensive reparse — is deleted; completion, semantic tokens, and folding all read through the one per-project cache. Config reloadsinvalidate()cached versions so the fast path stays sound acrossprisma-next.config.tschanges.TextDocumentsis retained as the text mirror / lifecycle / version source.src/server.ts): when the client advertisestextDocument.diagnostic, the server advertisesdiagnosticProviderand serves full reports throughensureCurrent;didOpen/didChangebecome invalidate-only (no eager publish), and config/watched-file changes sendworkspace/diagnostic/refresh(gated onrefreshSupport) instead of republishing. Clients without pull support keep the previous eager push behavior unchanged. Exactly one transport is ever active per client — structurally, since every push site is gated on the same capability flag. Flags ship as{ interFileDependencies: false, workspaceDiagnostics: false }with a scope comment: this reflects the current single-input implementation, not a property of PSL, and flips with the future multi-input symbol table.buildDocumentDiagnosticReport(project, uri)is project-scoped so the future multi-file table can attachrelatedDocumentsadditively — no rewrite needed.Why
publish+currentDocumentArtifact's per-request reparse with an O(n) whole-text compare) to dodge a stale-buffer race the LSP spec'sdidChangeordering guarantee already rules out. Freshness is now keyed on the monotonicversionthatTextDocumentsmaintains anyway.awaitbetween reading the buffer and deriving from it, so a derived result is always internally consistent for one version — tsserver's version-keyed lazy recompute fits; rust-analyzer-style snapshots/cancellation are unnecessary. Async stays confined to project/config resolution (executableprisma-next.config.ts, cached and de-duped).Validation
pnpm --filter @prisma-next/language-server test(187 tests, incl. no-reparse-at-unchanged-version, one-parse edit-then-complete, pull/push capability gating, refresh semantics), typecheck, lint; playground typecheck/lint.pnpm build,pnpm typecheck,pnpm lint:depsclean. (pnpm test:packageslocally red only in mongo-runtime/CLI tests that fail identically onmain— mongod-less machine.)publishDiagnosticsto the pull client, post-edit pull correct, tokens/folding healthy) — script + report underprojects/lsp-document-state/manual-qa*. Visual Monaco-marker check (Part B) pending a browser run.Non-goals
Removing
TextDocuments, the multi-input project-wide symbol table, multi-project membership,interFileDependencies: true/workspace/diagnostic, and any behavioral change to completion/semantic-tokens/folding beyond their data source. Seeprojects/lsp-document-state/spec.md§ Non-goals.